\documentclass[a4paper,12pt]{article}

\usepackage[margin=1.5cm]{geometry}
\usepackage{listings}
\usepackage{enumitem}

\title{Array VS. Pointer}
\author{Chen Rushan\\chenrsster@gmail.com}
\date{2009.11.19}

\setlength{\parskip}{1.2ex}
\setlength{\parindent}{0pt}

\lstset{
    frame=single, framesep=0pt, framexleftmargin=-1pt, framextopmargin=3pt,
    framexbottommargin=3pt, aboveskip=0.5cm, belowskip=0.2cm, columns=flexible,
    basicstyle=\ttfamily
}

\begin{document}

\maketitle

\begin{lstlisting}
 All the following is my personal opinion on array and pointer.
\end{lstlisting}

\section{Part 1}

    In C, a variable name is actually the literal representation of an address.
    For example, an array \verb=a[10]=, \verb=a= itself is an address, the value
    resides in this address is \verb=a[0]=, for a pointer \verb=p=, p itself is
    also an address, while the value resides in this address is another address.
    
    The difference between array and pointer lies in how they are treated by C.
    When an array name appears on RHS, C simply translates it into the address
    it represents, whereas when regular variable names (including pointer)
    appear on RHS, C will translate them into the value stored in the address
    that the name represents.
    
    With this knowledge, one can easily explain many wired things happening on
    array and pointers, as:
    
    \begin{itemize}[leftmargin=3ex]
        \item Why we can't declare an array as a pointer?
    
            The reason is that doing this will result in C changing the way in
            which the variable name is translated.
    
        \item Why we can equally write any of the following two code snippet?
    
            \begin{minipage}{5cm}
                \begin{lstlisting}[gobble=15]
                int a[10];
                *(a + i);
    
                \end{lstlisting}
            \end{minipage}
            \begin{minipage}{5cm}
                \begin{lstlisting}[gobble=15]
                int a[10];
                int *p = a;
                *(p + i);
                \end{lstlisting}
            \end{minipage}
    
            Note that for a pointer \verb=p=, even if you access element as
            \verb=p[i]=, \verb=p= is still replaced by the address stored in the
            address that \verb=p= represents, instead of simply the address that
            \verb=p= represents.
    \end{itemize}

\section{Part 2}

    Consider the following code snippet:

    \begin{lstlisting}[gobble=3]
    int apricot[2][3][5];
    
    int (*p)[3][5] = apricot;
    int (*r)[5] = apricot[i];
    int (*t) = apricot[i][j];
    int u = apricot[i][j][k];
    \end{lstlisting}
    
    This code seems rather confusing at first sight, but if you know the
    following secret, then it will become clear and easy to understand.
    
    \begin{lstlisting}[escapechar=\%, gobble=3]
    %\textbf{\em Arrays in C are all one-dimensional}%, any array is a one-dimensional array 
    of something, possibly another array.
    \end{lstlisting}

    Now let's see how to explain the above code.
    \begin{enumerate}
        \item For pointer \verb=p=:

            We know that \verb=apricot= is an array, and it's an array whose
            entry is another array of type \verb=int [3][5]=, so if you want a
            pointer to point to \verb=apricot=, you need a pointer pointing to
            an array of type \verb=int [3][5]=, just as shown above.

        \item For pointer \verb=r=:

            Since \verb=apricot[i]= is also an array, and its entry is array of
            type \verb=int [5]=, so we need to declare \verb=r= as
            \verb=int (*r)[5]=.

        \item \verb=t= and \verb=u= can be similarly interpreted.
    \end{enumerate}

\end{document}

